package com.woniuxy.springsecurity.filter;

import com.woniuxy.springsecurity.entity.LoginUserDetails;
import com.woniuxy.springsecurity.util.JwtUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.filter.OncePerRequestFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * @Author author
 * @Create 2023-10-27 9:51
 */
//Filter是JavaWeb中的原生的过滤器    doFilter
//OncePerRequestFilter是Spring框架封装的过滤器
@Component
public class JwtAuthentiactionFilter extends OncePerRequestFilter {
    @Autowired
    RedisTemplate<String,Object> redisTemplate;

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        //请求携带token，进行token校验
        String token = request.getHeader("token");
        if(StringUtils.isEmpty(token)){
            //没有token，放行其实是拦截:SpringSecurity框架底层有拦截器
            filterChain.doFilter(request, response);
            return;
        }
        if(!JwtUtil.validate(token)){
            throw new RuntimeException("token无效");
        }
        //token有效，记录到Security上下文中，告诉后面的拦截器，可以放行
        //可以从redis获取完整的用户信息
        //现在没有存，还是模拟数据库查询
        String username = JwtUtil.getEname(token);
        //从reids中获取
//        User user=null;
//        List<String> permissions=new ArrayList<>();
//        //从数据库根据用户名查询用户信息
//        if("a".equals(username)){
//            user=new User(1,"a","$2a$10$CEhZfCMH2KzVVT0Ex6UoDeDLyZ51WevCXKshr3X63kOzrjCYW70d2");
//            permissions.add("test");
//            permissions.add("add");
//        }else if("b".equals(username)){
//            user=new User(2,"b","$2a$10$SXKszBA016Vpc97fbWh5L.1MrEHF0k5jd5qyrbWkc1feuDSeGrNk6");
//            permissions.add("test");
//        }else{
//            throw new RuntimeException("用户名不存在");
//        }
//        LoginUserDetails userDetails=new LoginUserDetails(user,permissions);
        LoginUserDetails userDetails= (LoginUserDetails) redisTemplate.opsForValue().get("user:"+username);
        //一定要用三个的参数:第三个参数是权限，super.setAuthenticated(true);
        //Object principal,     身份信息
        // Object credentials,  凭证，我们使用token，null不影响使用
        //Collection<? extends GrantedAuthority> authorities，先写null，处理权限，就要查询权限
        Authentication authentication=new UsernamePasswordAuthenticationToken(userDetails,null,userDetails.getAuthorities());
        //将通过token验证的信息，写入sercuity上下午，权限框架的过滤器就不会再拦截了
        SecurityContextHolder.getContext().setAuthentication(authentication);

        System.out.println("JWT通过");
        filterChain.doFilter(request, response);
    }
}
